<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      height: 1800px;
    }
    img {
      display: block;
      width: 450px;
      height: 300px;
      border: 1px solid red;
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <img src="" data-src="https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg">
  <img src="" data-src="https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg">
  <img src="" data-src="https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg">
  <img src="" data-src="https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg">
  <img src="" data-src="https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg">
  <!-- 图片不设置 src 属性 不会报错，只是会加载空白 -->
  <img src="" alt="无法加载资源" data-src="">

  <script>
    // 节流函数
    function throttle(fn, interval) {
      let last = 0;
      return function(...args) {
        let now = +new Date();
        if (now - last < interval) return ;
        fn.apply(this, args);
        last = now;
      };
    }

    // 方案一
    function lazyload() {
      // 1.获取视口高度
      let viewHeight = document.documentElement.clientHeight;
      // 2.获取滚动条上下滚动的高度
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      // 3.获取图片元素
      let imgEles = document.getElementsByTagName('img');
      // 4.遍历判断当前图片是否出现在视口中，出现的话就把图片的 src 属性修改成自定义属性的值
      for (let i = 0; i < imgEles.length; i++) {
        // 5.图片距离顶部的距离 < 当前滚动条距顶部的距离 + 视口的高度 => 当前图片已经进入了视口
        if (imgEles[i].offsetTop < scrollTop + viewHeight) {
          // 6.如果当前图片设定为默认图片，则修改其 src 属性为自定义属性 data-src 的值
          if (imgEles[i].src.indexOf('/images/default.jpeg') !== -1) {
            imgEles[i].src = imgEles[i].getAttribute('data-src');
          }
        }
      }
    }

    // 监听 srcoll 事件，并且避免 scroll 事件频繁触发，对 scroll 事件做节流处理
    // window.addEventListener('scroll', throttle(lazyload, 200));

    function lazyload2() {
      // 1.获取图片元素
      let imgEles = document.getElementsByTagName('img');
      const observer = new IntersectionObserver(watchers => {
        // watchers 指向被观察的元素
        for (let i = 0; i < watchers.length; i++) {
          // 判断当前被观察元素是否出现在视口
          if (watchers[i].isIntersecting) {
            const imgEle = watchers[i].target;
            imgEle.src = imgEle.getAttribute('data-src');
            // 去除对该元素的观察
            observer.unobserve(imgEle);
          }
        }
      })
      // 把获取的 img 的所有元素节点类数组 HtmlCollection 转换成数组之后遍历给每个 img 元素使用 observer 对象进行观察
      Array.from(imgEles).forEach(item => observer.observe(item));
    }

    lazyload2();
  </script>
</body>
</html>